using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace FoundationLib.AddIns.Constraints
{
	/// <summary>
	/// Represents an Object Constraint Language statement
	/// </summary>
	public abstract class OclStatement : IVisitable
	{
		/// <summary>
		/// The original value of the OCL statement
		/// </summary>
		private string value;
		/// <summary>
		/// The name of the element
		/// </summary>
		private string name;

		/// <summary>
		/// The regular expression pattern to use
		/// </summary>
		private const string PATTERN = @"^(pre|post|inv|PRE|POST|INV) ?:";

		/// <summary>
		/// Gets or sets the OCL statement value
		/// </summary>
		public string Value
		{
			get
			{
				return this.value;
			}
			set
			{
				this.value = value;
			}
		}

		/// <summary>
		/// Gets or sets the name of the element
		/// </summary>
		public string Name
		{
			get
			{
				return this.name;
			}
			set
			{
				this.name = value;
			}
		}

		/// <summary>
		/// Creates a new Object Constraint Language statement
		/// </summary>
		/// <param name="value">The OCL statement value</param>
		/// <param name="name">The OCL statement name</param>
		protected OclStatement(string value, string name)
		{
			if (String.IsNullOrWhiteSpace(value))
				throw new ArgumentNullException("value");

			this.value = this.RemoveConstraintType(WebUtility.HtmlDecode(value));
			this.name = name != null ? name.Replace("\"", "'") : null;
		}

		/// <summary>
		/// Removes any constraint type defined by PATTERN from the given string value.
		/// </summary>
		/// <returns>The resulting string after replacement</returns>
		/// <param name="input">The string value</param>
		private string RemoveConstraintType(string input)
		{
			Regex regex = new Regex(PATTERN);
			string result = regex.Replace(input.Trim(), (x) =>
			{
				return String.Empty;
			});
			return result.Trim();
		}

		/// <summary>
		/// Accepts a visitor
		/// </summary>
		/// <param name="visitor">The visitor</param>
		public void Accept(IVisitor visitor)
		{
			if (visitor == null)
				throw new ArgumentNullException("visitor");
			visitor.Visit(this);
		}
	}
}
